    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   1

          1                         ;^Z80^
          2                         ; modem control information
          3                         ; Coleco 300 baud direct connect modem
          4                         ;      4/5/84
          5                         ;
          6                         ; Data port = 05EH
          7                         ; Control port = 05FH
          8                         ;
          9                         ; Useful equates
         10           005E          DATAP   EQU     05EH
         11           005F          CTRLP   EQU     05FH
         12                         ;
         13                         ;     Mode instruction values
         14           0080          NULL    EQU     080H
         15                         ;
         16                         ; To generate mode byte, select one from column A
         17                         ; and one from column B. See your INTEL dealer for optional
         18                         ; accessories. Add these all together, and spit 'em out.
         19                         ; Chef's suggestion: DEFAULT EQU  STPB1+BITS7+PEN+EP
         20                         ;                    [7 bits, 1 stop bit, even parity]
         21                         ;
         22                         ; column A
         23           0040          STPB1   EQU     040H    ; 1 stop bit
         24           0080          STPB15  EQU     080H    ; 1 1/2 stop bits
         25           00C0          STPB2   EQU     0C0H    ; 2 stop bits
         26                         ; column B
         27           0000          BITS5   EQU     000H    ; 5 bits/char
         28           0004          BITS6   EQU     004H    ; 6 bits/char
         29           0008          BITS7   EQU     008H    ; 7 bits/char
         30           000C          BITS8   EQU     00CH    ; 8 bits/char
         31                         ; optional accessories
         32           0020          EP      EQU     020H    ; 1=even parity, 0=odd
         33           0010          PEN     EQU     010H    ; 1=enable parity, 0=disable
         34                         ; required options
         35                         ;  ---> The only one applicable here is 300 baud!!!  <---
         36           0003          X64     EQU     003H    ; 64x clock rate [300 baud]
         37                         ;
         38                         ; the assumed default value
         39           00CC          DEFAULT EQU     STPB2+BITS8     ; 8 bits, 2 stops, no parity
         40                         ; Command instruction values
         41                         ;
         42                         ; Select desired functions, then add to get command byte
         43                         ;
         44           0080          EHM     EQU     080H    ; 1=enter hunt mode [no effect on async op]
         45                                                 ; [same as NULL]
         46           0040          IR      EQU     040H    ; 1=internal reset
         47           0020          RTS     EQU     020H    ; 1=set RTS to 0, enable transmitter
         48           0010          ER      EQU     010H    ; 1=reset error conditions
         49           0008          SBRK    EQU     008H    ; 1=send break [TXD goes "low"]
         50           0004          RXE     EQU     004H    ; 1=receive enable
         51           0001          TXE     EQU     001H    ; 1=transmit enable
         52           0002          DTR     EQU     002H    ; set DTR to 0, seize phone line
         53                         ;
         54                         ; Note this important stuff  |
         55                         ;                            V
         56                         ; 1:    If DTR ever gets set to 0, [SZ or preset goes low] then

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   2

         57                         ;       modem goes to originate mode.
         58                         ; 2:    Once line is seized, DTR is set to 1, ^SZ is low, so
         59                         ;       7474 has preset=H, data=L,.html clear=H. In this condition,
         60                         ;       toggling clock [RTS or ^TXE] will change to answer mode
         61                         ;
         62                         ; So what?
         63                         ;
         64                         ; With phone hung up, modem is in originate mode. To seize line,
         65                         ; set DTR and RTS to 1 [this drops ^SZ]. This grabs phone line
         66                         ; and enables carrier.
         67                         ; To switch to answer mode, set RTS to 0 then back to 1.
         68                         ;
         69                         ;  STATUS BITS
         70                         ;
         71           0000          TXRDY   EQU     0               ; indicates transmitter empty
         72           0001          RXRDY   EQU     1               ; indicates valid character ready
         73           0002          TXMT    EQU     2               ; indicates buffer empty
         74           0003          P_ERR   EQU     3               ; set when parity error detected
         75           0004          OE      EQU     4               ; set on overrun error
         76           0005          FE      EQU     5               ; set on framing error
         77           0006          BD      EQU     6               ; set when break detected
         78           0007          DSR     EQU     7               ; indicated carrier detect
         79           0007          CD      EQU     DSR
         80                         ;
         81                         ; data areas
         82   0000' 80              C_DATA  DEFB    NULL            ; current 8251 command
         83                         ;
         84                         ; global subroutine names
         85                         ;
         86                                 GLOBAL  DELAY,DIAL,SEIZE,ANSMOD
         87                                 GLOBAL  HANGUP,CD_STAT,U_STAT
         88                                 GLOBAL  CHR_IN,CHR_OUT,M_INIT
         89                                 GLOBAL  SET_UART
         90                         ;
         91                         ;***************************************************************************
         92                         ; SUBROUTINES
         93                         ;***************************************************************************
         94                         ;
         95                         ; Wait 10 msec
         96   0001'                 DELAY:
         97   0001' F5                      PUSH            AF              ; [3 uSEC]
         98   0002' C5                      PUSH            BC              ; [3]
         99   0003' D5                      PUSH            DE              ; [3]
        100   0004' E5                      PUSH            HL              ; [3]
        101   0005' 21 0000                 LD              HL,0            ; [2.5]
        102   0008' 11 0000                 LD              DE,0            ; [2.5]
        103   000B' 01 3606                 LD              BC,1590
        104                         ; with all the pushes and pops, we've used about 32 uSEC.
        105                         ; we need a total of 2,000 LDIRs less 7
        106                         ; BUT this is off a bit, so we have to go about 18% faster
        107   000E' ED B0                   LDIR
        108   0010' E1                      POP             HL              ; [3]
        109   0011' D1                      POP             DE              ; [3]
        110   0012' C1                      POP             BC              ; [3]
        111   0013' F1                      POP             AF              ; [3]
        112   0014' C9                      RET
        113                         ;

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   3

        114                         ; *************************************
        115                         ; DIAL DIGIT
        116                         ;  ENTRY: A=ASCII DIGIT 0-9
        117                         ;  EXIT:  NONE
        118   0015'                 DIAL:
        119   0015' F5                      PUSH            AF
        120   0016' C5                      PUSH            BC
        121   0017' D5                      PUSH            DE
        122   0018' E5                      PUSH            HL
        123                         ;thaT
        124   0019' FE 50                   CP              'P'
        125   001B' 28 36                   JR              Z,PAUSE
        126   001D' FE 70                   CP              'p'
        127   001F' 28 32                   JR              Z,PAUSE
        128   0021' FE 2C                   CP              ','             ;Comma=pause
        129   0023' 28 2E                   JR              Z,PAUSE
        130   0025' FE 3A                   CP              '9'+1
        131   0027' 30 31                   JR              NC,BAD_DGT      ;if character >= ':' then we lose
        132   0029' FE 30                   CP              '0'
        133   002B' 38 2D                   JR              C,BAD_DGT               ;if char < '0' then we lose
        134   002D' 20 02                   JR              NZ,CHAR_OK
        135                         ; an ASCII 0 means 10 pulses, so start with '9'+1
        136   002F' 3E 3A                   LD              A,'9'+1
        137   0031'                 CHAR_OK:
        138   0031' D6 30                   SUB             '0'
        139   0033' 47                      LD              B,A                     ;number of pulses is now in B
        140                         ;
        141   0034'                 PLSE_LP:
        142                         ; All dialing is in originate mode. We assume that the line was
        143                         ; already seized.
        144                         ;
        145                         ; unseize line for 18/29 of the 100 ms pulse time [60 ms]
        146   0034' 3E 25                   LD              A,RXE+TXE+RTS
        147   0036' D3 5F                   OUT             (CTRLP),A       ;PICK UP
        148   0038' C5                      PUSH            BC
        149   0039' 06 06                   LD              B,6
        150   003B'                 PLP1:
        151   003B' CD 0100'                CALL            DELAY
        152   003E' 10 FB                   DJNZ            PLP1
        153   0040' C1                      POP             BC
        154                         ; seize line for 11/29 of the 100 ms pulse time [40 ms]
        155   0041' 3E 27                   LD              A,RXE+TXE+RTS+DTR
        156   0043' D3 5F                   OUT             (CTRLP),A       ;PICK UP
        157   0045' C5                      PUSH            BC
        158   0046' 06 04                   LD              B,4
        159   0048'                 PLP2:
        160   0048' CD 0100'                CALL            DELAY
        161   004B' 10 FB                   DJNZ            PLP2
        162   004D' C1                      POP             BC
        163                         ;
        164                         ; next pulse
        165   004E' 10 E4                   DJNZ            PLSE_LP
        166
        167   0050' 32 0000'                LD              (C_DATA),A              ;SAVE LAST VALUE
        168                         ;
        169                         ; delay between digits
        170   0053'                 PAUSE:

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   4

        171   0053' 06 50                   LD              B,80                    ;800 ms
        172   0055'                 PLP3:
        173   0055' CD 0100'                CALL            DELAY
        174   0058' 10 FB                   DJNZ            PLP3
        175   005A'                 BAD_DGT:
        176   005A' E1                      POP             HL
        177   005B' D1                      POP             DE
        178   005C' C1                      POP             BC
        179   005D' F1                      POP             AF
        180   005E' C9                      RET
        181
        182                         ; ***************************
        183                         ; SEIZE LINE
        184                         ;  ENTRY: A=0 FOR ORIGINATE MODE
        185                         ;         A-0FFH FOR ANSWER MODE
        186                         ;  EXIT:  CARRIER IS ENABLED
        187                         ;         REGS A & C GET TRASHED
        188   005F'                 SEIZE:
        189   005F' 4F                      LD              C,A             ; SAVE
        190   0060' CD 7900'                CALL            HANGUP
        191   0063' 3E 27                   LD              A,RXE+TXE+RTS+DTR
        192   0065' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
        193   0068' D3 5F                   OUT             (CTRLP),A       ; PICK UP
        194   006A' 79                      LD              A,C
        195   006B' B7                      OR              A
        196   006C' C8                      RET             Z               ; ALL DONE
        197                         ; *****************
        198                         ; ANSWER MODE
        199                         ; SWITCHES MODEM DIRECTLY TO ANSWER MODE
        200                         ; Assumes modem off-hook
        201                         ;    EXIT:  REG A TRASHED
        202   006D'                 ANSMOD:
        203                         ; ONE FULL PULSE OF RTS LINE
        204   006D' 3E 07                   LD              A,RXE+TXE+DTR
        205   006F' D3 5F                   OUT             (CTRLP),A
        206   0071' 3E 27                   LD              A,RXE+TXE+RTS+DTR
        207   0073' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
        208   0076' D3 5F                   OUT             (CTRLP),A
        209   0078' C9                      RET
        210                         ; **********************
        211                         ; HANGUP
        212                         ;    HANGS UP PHONE. TRASHES REG A
        213                         ;
        214   0079'                 HANGUP:
        215   0079' 3E 25                   LD              A,RXE+TXE+RTS
        216   007B' 32 0000'                LD              (C_DATA),A      ; SAVE LAST COMMAND
        217   007E' D3 5F                   OUT             (CTRLP),A       ; HANG UP PHONE AND SWITCH TO ORIGINATE MODE
        218   0080' C9                      RET
        219                         ; **********************
        220                         ; CARRIER_STATUS
        221                         ;   READS STATUS FROM UART AND MODEM CHIP
        222                         ;       ENTRY:
        223                         ;       EXIT:   NZ=CARRIER DETECT
        224                         ;               Z=NO CARRIER
        225   0081'                 CD_STAT:
        226   0081' DB 5F                   IN              A,(CTRLP)
        227   0083' CB 7F                   BIT             DSR,A

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   5

        228   0085' C9                      RET
        229                         ; **********************
        230                         ; UART_STATUS
        231                         ;   CHECKS UART FOR ERRORS AND/OR DATA
        232                         ;       ENTRY:
        233                         ;       EXIT:   NC=NO ERRORS
        234                         ;               C=DATA ERROR
        235                         ;               NZ=CHARACTER PRESENT
        236                         ;               Z=NO CHARACTER
        237   0086'                 U_STAT:
        238   0086' DB 5F                   IN              A,(CTRLP)
        239   0088' B7                      OR              A
        240   0089' 18 01                   JR              URT_CMN
        241   008B'                 URT_ERR:
        242   008B' 37                      SCF
        243   008C'                 URT_CMN:
        244   008C' CB 4F                   BIT             RXRDY,A
        245   008E' C9                      RET
        246                         ; ************************
        247                         ; CHARACTER_IN
        248                         ;       ENTRY:
        249                         ;       EXIT:   A=CHARACTER FROM MODEM
        250                         ;               NC=NO ERROR
        251                         ;               C=DATA ERROR
        252
        253   008F'                 CHR_IN:
        254   008F' CD 8600'                CALL            U_STAT
        255   0092' 28 FB                   JR              Z,CHR_IN        ;WAIT FOR CHARACTER
        256   0094' DB 5E                   IN              A,(DATAP)
        257   0096' B7                      OR              A
        258   0097' C9                      RET
        259   0098'                 CHR_ERR:
        260   0098' 3A 0000'                LD              A,(C_DATA)
        261   009B' F6 10                   OR              ER              ;clear for errors
        262   009D' D3 5F                   OUT             (CTRLP),A
        263   009F' EE 10                   XOR             ER              ;disable error reset
        264   00A1' D3 5F                   OUT             (CTRLP),A
        265   00A3' 3E 00                   LD              A,0
        266   00A5' C9                      RET
        267                         ; *********************
        268                         ; CHARACTER_OUT
        269                         ;       ENTRY:  A=CHARACTER TO TRANSMIT
        270                         ;       EXIT:   NONE
        271   00A6'                 CHR_OUT:
        272   00A6' F5                      PUSH            AF
        273                         ; WAIT UNTIL TRANSMITTER CLEAR
        274   00A7'                 CHR_L1:
        275   00A7' DB 5F                   IN              A,(CTRLP)
        276   00A9' CB 57                   BIT             TXMT,A
        277   00AB' 28 FA                   JR              Z,CHR_L1
        278                         ; DUMP THE SUCKER OUT
        279   00AD' F1                      POP             AF
        280   00AE' D3 5E                   OUT             (DATAP),A
        281   00B0' C9                      RET
        282                         ; *************************
        283                         ; MODEM_INIT
        284                         ;   PRESETS MODEM TO KNOWN INITIAL STATE

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   6

        285   00B1'                 M_INIT:
        286   00B1' 3E 80                   LD              A,NULL
        287   00B3' 32 0000'                LD              (C_DATA),A      ; fool it into hanging up
        288   00B6' 3E CC                   LD              A,DEFAULT       ; desired default value
        289
        290                         ; *************************
        291                         ; SET_UART
        292                         ;   SETS UART TO DESIRED STOP BITS, PARITY, ETC
        293                         ;       ENTRY:  A=stop bits + bits/char + parity
        294                         ;       EXIT:   NONE
        295   00B8'                 SET_UART:
        296   00B8' F6 03                   OR              X64             ; clock rate is always 64x
        297   00BA' F5                      PUSH            AF
        298   00BB' 3E 80                   LD              A,080H
        299   00BD' D3 5F                   OUT             (CTRLP),A
        300   00BF' D3 5F                   OUT             (CTRLP),A       ; get the 8251's attention
        301   00C1' 3E 40                   LD              A,040H
        302   00C3' D3 5F                   OUT             (CTRLP),A
        303   00C5' F1                      POP             AF
        304   00C6' D3 5F                   OUT             (CTRLP),A       ; dump the init value out
        305   00C8' 3A 0000'                LD              A,(C_DATA)
        306   00CB' D3 5F                   OUT             (CTRLP),A
        307   00CD' C9                      RET

         0 Error(s) Detected.   206 Program Bytes.
        54 Symbols Detected.

    FILE: MODDOC:MODEM       HEWLETT-PACKARD: Z80 Assembler                                        Tue,  9 Oct 1984, 11:26     Page   7

    Value   Symbol          Defined         Referenced:

    006D' ANSMOD               202      86
    005A' BAD_DGT              175     131   133
    0006  BD                    77
    0000  BITS5                 27
    0004  BITS6                 28
    0008  BITS7                 29
    000C  BITS8                 30      39
    0007  CD                    79
    0081' CD_STAT              225      87
    0031' CHAR_OK              137     134
    0098' CHR_ERR              259
    008F' CHR_IN               253      88   255
    00A7' CHR_L1               274     277
    00A6' CHR_OUT              271      88
    005F  CTRLP                 11     147   156   193   205   208   217   226   238   262   264   275   299   300   302   304   306
    0000' C_DATA                82     167   192   207   216   260   287   305
    005E  DATAP                 10     256   280
    00CC  DEFAULT               39     288
    0001' DELAY                 96      86   151   160   173
    0015' DIAL                 118      86
    0007  DSR                   78      79   227
    0002  DTR                   52     155   191   204   206
    0080  EHM                   44
    0020  EP                    32
    0010  ER                    48     261   263
    0005  FE                    76
    0079' HANGUP               214      87   190
    0040  IR                    46
    00B1' M_INIT               285      88
    0080  NULL                  14      82   286
    0004  OE                    75
    0053' PAUSE                170     125   127   129
    0010  PEN                   33
    003B' PLP1                 150     152
    0048' PLP2                 159     161
    0055' PLP3                 172     174
    0034' PLSE_LP              141     165
    0003  P_ERR                 74
    0020  RTS                   47     146   155   191   206   215
    0004  RXE                   50     146   155   191   204   206   215
    0001  RXRDY                 72     244
    0008  SBRK                  49
    005F' SEIZE                188      86
    00B8' SET_UART             295      89
    0040  STPB1                 23
    0080  STPB15                24
    00C0  STPB2                 25      39
    0001  TXE                   51     146   155   191   204   206   215
    0002  TXMT                  73     276
    0000  TXRDY                 71
    008C' URT_CMN              243     240
    008B' URT_ERR              241
    0086' U_STAT               237      87   254
    0003  X64                   36     296